﻿#include "cwebsocketclient.h"
#include "QtWebSockets/qwebsocket.h"

#include <QTextCodec>
#include <QJsonObject>
#include <QJsonDocument>
#include <QFileInfo>
#include <QCoreApplication>
#include <QEventLoop>
#include <QByteArray>
#include <QDir>

QT_USE_NAMESPACE

CWebSocketClient::CWebSocketClient(QObject *parent) :
    QObject(parent)
{
    connect(&m_webSocket, &QWebSocket::connected, this, &CWebSocketClient::onConnected);
    connect(&m_webSocket, &QWebSocket::disconnected, this, &CWebSocketClient::onDisconnected);
    connect(&m_webSocket, &QWebSocket::textMessageReceived,this, &CWebSocketClient::onTextMessageReceived);

    QObject::connect(&m_WebSocketHeartTimeOutTimer, &QTimer::timeout, this, &CWebSocketClient::handleWebSocketHeartTimeOut);
    m_WebSocketHeartTimeOutTimer.setInterval(5000);

    QObject::connect(&m_WebSocketReconnectTimer, &QTimer::timeout, this, &CWebSocketClient::handleWebSocketReconnect);
    m_WebSocketReconnectTimer.setInterval(5000);
}

CWebSocketClient::~CWebSocketClient()
{
    m_webSocket.close();
}

/**
 * @brief CWebSocketClient::Open 打开指定地址的网络连接
 * @param url 要打开的网址
 */
void CWebSocketClient::Open(QUrl url)
{
    m_websocketurl = url;
    m_webSocket.open(m_websocketurl);
}

/**
 * @brief CWebSocketClient::Send 发送字符串
 * @param msg 要发送的字符串
 * @return 返回发送成功的字符串长度
 */
qint64 CWebSocketClient::Send(QString msg)
{
    if(msg.isEmpty())
        return 0;

    return m_webSocket.sendTextMessage(msg);
}

/**
 * @brief CWebSocketClient::Close 关闭连接
 */
void CWebSocketClient::Close(void)
{
    m_WebSocketHeartTimeOutTimer.stop();
    m_WebSocketReconnectTimer.stop();
    m_webSocket.close();
}

/**
 * @brief CWebSocketClient::onConnected 连接成功后的处理
 */
void CWebSocketClient::onConnected()
{
    m_WebSocketHeartTimeOutTimer.start();
    m_WebSocketReconnectTimer.stop();

    emit socketconnected(this);
}

/**
 * @brief CWebSocketClient::onDisconnected 连接断开后的处理
 */
void CWebSocketClient::onDisconnected()
{
    emit socketdisconnected(this);

    m_WebSocketHeartTimeOutTimer.stop();
    m_WebSocketReconnectTimer.start();
}

/**
 * @brief CWebSocketClient::handleWebSocketReconnect 处理客户端断开后重连
 */
void CWebSocketClient::handleWebSocketReconnect()
{
    if(m_websocketurl.isValid())
    {
        m_webSocket.open(m_websocketurl);
    }
}

/**
 * @brief CWebSocketClient::handleWebSocketHeartTimeOut 处理心跳消息
 */
void CWebSocketClient::handleWebSocketHeartTimeOut()
{
    m_webSocket.sendTextMessage("100");
}

/**
 * @brief CWebSocketClient::onTextMessageReceived 处理接收到字符串时的情况
 * @param message 接收到的字符串
 */
void CWebSocketClient::onTextMessageReceived(QString message)
{
    emit socketmessage(this,message);
}

CWebSocketClientManager::CWebSocketClientManager()
{

}

CWebSocketClientManager::~CWebSocketClientManager()
{
    clearAllClients();
}

/**
 * @brief CWebSocketClientManager::clearAllClients 清除所有的客户端
 */
void CWebSocketClientManager::clearAllClients(void)
{
    QHash<QString,CWebSocketClient*>::iterator iter = m_WebSocketClients.begin();
    for(;iter != m_WebSocketClients.end();++iter)
    {
        if((*iter))
        {
            (*iter)->disconnect();
            delete (*iter);
        }
        (*iter) = NULL;
    }

    m_WebSocketClients.clear();
}

/**
 * @brief CWebSocketClientManager::addClient 添加一个客户端
 * @param clientName 要添加的客户端的名称
 * @param pClient 要添加的客户端
 * @return 如果客户端添加成功返回真，否则返回假
 */
bool CWebSocketClientManager::addClient(QString clientName,CWebSocketClient* pClient)
{
    if(clientName.isEmpty() || pClient == NULL)
        return false;

    CWebSocketClient *pReturnClient = getClient(clientName);
    if(pReturnClient)
        return false;

    m_WebSocketClients[clientName] = pClient;

    return true;
}

/**
 * @brief CWebSocketClientManager::getClient 得到一个客户端
 * @param clientName 要得到的客户端的名称
 * @return 如果存在这个客户端返回这个客户端，否则返回NULL
 */
CWebSocketClient* CWebSocketClientManager::getClient(QString clientName)
{
    QHash<QString,CWebSocketClient*>::iterator iter = m_WebSocketClients.find(clientName);
    if(iter != m_WebSocketClients.end())
        return (*iter);

    return NULL;
}

/// 清除指定的客户端
bool CWebSocketClientManager::deleteClient(QString clientName)
{
    if(clientName.isEmpty() || m_WebSocketClients.isEmpty())
        return false;

    QHash<QString,CWebSocketClient*>::iterator iter = m_WebSocketClients.find(clientName);
    if(iter != m_WebSocketClients.end())
    {
        (*iter)->Close();

        delete (*iter);
        (*iter) = NULL;

        m_WebSocketClients.erase(iter);

        return true;
    }

    return false;
}

